using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace GameEditor.Common.Controls
{

    public class AlphaPicker : Control
    {
        private const int VPadding = 10;
        private Bitmap bitmap = null;

        public AlphaPicker()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            //generate bitmap
            GenerateColor(Color.Black);
        }
        public event EventHandler ValueChanged;
        private int alpha;

        public int Alpha
        {
            get { return alpha; }
            set { alpha = value; }
        }

        public void GenerateColor(Color baseColor)
        {
            if (bitmap != null)
                bitmap.Dispose();

            bitmap = new Bitmap(20, 152, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            int cellSize = 5;
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                for (int y = 0; y < bitmap.Height; y += cellSize)
                {
                    bool useGrayBrush = (y & 1) == 1;
                    for (int x = 0; x < bitmap.Width; x += cellSize)
                    {
                        useGrayBrush = !useGrayBrush;
                        Brush brush = useGrayBrush ? Brushes.Gray : Brushes.White;
                        g.FillRectangle(brush, new Rectangle(x, y, cellSize, cellSize));
                    }
                }
                //draw gradient cover
                using (LinearGradientBrush brush = new LinearGradientBrush(
                    new Point(0, 0), new Point(0, bitmap.Height),
                    Color.FromArgb(0, baseColor), Color.FromArgb(255, baseColor)))
                {
                    g.FillRectangle(brush, new Rectangle(Point.Empty, bitmap.Size));
                }
            }
        }
        protected override void Dispose(bool disposing)
        {
            bitmap.Dispose();
            base.Dispose(disposing);
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            Rectangle imageRect = new Rectangle(0, VPadding, bitmap.Width, Height - 2 * VPadding);
            g.DrawImage(bitmap, imageRect);

            //draw arrow
            int arrowTop = MathHelper.IntervalMap(
                alpha > 255 ? 255 : alpha,
                new GameEditor.Common.Range<int>(0, 255),
                new GameEditor.Common.Range<int>(VPadding, Height - VPadding)
                );

            Point pt1 = new Point(bitmap.Width, arrowTop);
            Point pt2 = new Point(pt1.X + 10, pt1.Y - 5);
            Point pt3 = new Point(pt1.X + 10, pt1.Y + 5);

            using (GraphicsPath path = new GraphicsPath())
            {
                path.StartFigure();
                path.AddLine(pt1, pt2);
                path.AddLine(pt2, pt3);
                path.AddLine(pt3, pt1);
                path.CloseFigure();
                g.FillPath(Brushes.White, path);
            }
            g.DrawLine(Pens.Black, pt1, pt2);
            g.DrawLine(Pens.Black, pt1, pt3);
            g.DrawLine(Pens.Black, pt2, pt3);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.Button == MouseButtons.Left)
                UpdateParameter(e.Location);
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
                UpdateParameter(e.Location);
        }
        private void UpdateParameter(Point location)
        {
            alpha = MathHelper.IntervalMap
                (location.Y,
                new GameEditor.Common.Range<int>(VPadding, Height - VPadding),
                new GameEditor.Common.Range<int>(0, 255));
            alpha = MathHelper.Clamp(0, 255, alpha);
            if (ValueChanged != null)
                ValueChanged(this, EventArgs.Empty);
            Invalidate();
        }

    }

}
